<template>
  <div class="part">
    <div class="editor">
      <div class="editor-header">
        <i class="iconfont"
           @click="getResult()">&#xe77c;</i>
        <i class="iconfont"
           @click="undo()">&#xe774;</i>
        <i class="iconfont"
           @click="redo()">&#xe77d;</i>
        <i class="iconfont"
           @click="refresh()">&#xe772;</i>
        <i class="iconfont"
           @click="clear()">&#xe777;</i>
      </div>
      <textarea id="coder"
                v-model="code" />
    </div>
    <div class="editor-output">
      <div class="output-header">运行结果</div>
      <template v-if="!!output.problem_id">
        <div v-if="output.problem_result===output.out"
             class="output-tips"
             style="color:green;">已完成</div>
        <div v-else
             class="output-tips"
             style="color:red;">失败</div>
        <div class="output-row">
          <div class="output-title">输入</div>
          <div class="output-content">{{ output.problem_in }}</div>
        </div>
        <div class="output-row">
          <div class="output-title">输出</div>
          <div id="output"
               class="output-content">{{ output.out||output.err }}</div>
        </div>
        <div class="output-row">
          <div class="output-title">预计结果</div>
          <div class="output-content">{{ output.problem_result }}</div>
        </div>
      </template>
    </div>
  </div>
</template>

<script>
import { _debounce } from '@/utils/debounce'
import { mapGetters } from 'vuex'
import { judge } from '@/api/code'

// 引入全局实例
import _CodeMirror from 'codemirror'
import 'codemirror/lib/codemirror.css'
import 'codemirror/theme/neo.css'
import 'codemirror/mode/python/python'
// 设置光标所在行高亮
import 'codemirror/addon/selection/active-line'
// 设置滚动栏
import 'codemirror/addon/scroll/simplescrollbars.css'
import 'codemirror/addon/scroll/simplescrollbars'
// 括号匹配
import 'codemirror/addon/edit/matchbrackets'
import 'codemirror/addon/edit/closebrackets'
// 代码折叠
import 'codemirror/addon/fold/foldcode'
import 'codemirror/addon/fold/foldgutter.css'
import 'codemirror/addon/fold/foldgutter'
import 'codemirror/addon/fold/brace-fold'
import 'codemirror/addon/fold/indent-fold'
import 'codemirror/addon/fold/comment-fold'
// 自动提示
import 'codemirror/addon/hint/show-hint'
import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/addon/hint/anyword-hint'
// 获取全局实例
const CodeMirror = window.CodeMirror || _CodeMirror
export default {
  props: {
    preset: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      output: {},
      code: '',
      mode: 'x-python',
      editor: null,
      options: {
        tabSize: 2,
        theme: 'neo',
        lineNumbers: true,
        cursorHeight: 0.85,
        scrollbarStyle: 'overlay', // 滚动条形式(null/simple/overlay)
        styleActiveLine: true, // 光标所在行高亮
        smartIndent: true, // 智能缩进
        indentWithTabs: true,
        matchBrackets: true, // 括号匹配
        autoCloseBrackets: true,
        showCursorWhenSelecting: true,
        extraKeys: {
          'Ctrl-Q': 'autocomplete',
          'Alt-Q': function (cm) { cm.foldCode(cm.getCursor()) }
        },
        hintOptions: { // 自动补全
          completeSingle: false
        },
        foldGutter: true, // 代码折叠
        lineWrapping: true,
        gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter']
      }
    }
  },
  computed: { ...mapGetters(['userid']) },
  watch: {
    preset (val) {
      this.editor.setValue(val)
    }
  },
  mounted () {
    this.initEditor()
  },
  methods: {
    initEditor () {
      // 初始化编辑器实例，传入需要被实例化的文本域对象和默认配置
      this.editor = CodeMirror.fromTextArea(document.getElementById('coder'), this.options)
      this.editor.setValue(this.code)
      this.editor.setSize('auto', '540px')
      this.editor.on('change', (editor) => { // 双向绑定code
        this.code = editor.getValue()
      })
      this.editor.on('keypress', () => { // 自动提示
        this.editor.showHint()
      })
    },
    undo () {
      this.editor.undo()
    },
    redo () {
      this.editor.redo()
    },
    refresh () {
      this.editor.refresh()
      this.editor.setValue(this.preset)
      this.output = {}
    },
    getResult: _debounce(function () {
      judge(this.code, this.userid, this.$route.params.problemId)
        .then(res => {
          console.log(res)
          this.output = res.data
          const out = res.data.out
          const output = document.querySelector('#output')
          if (out !== '') {
            output.style.color = '#212121'
          } else {
            output.style.color = '#f56c6c'
          }
        })
        .catch(error => {
          console.log(error)
        })
    }, 300),
    clear () {
      this.editor.setValue('')
      this.output = {}
    }
  }
}
</script>
<style lang="stylus" scoped>
@import '~styles/varibles.styl'

.part
  .editor
    height 70%
    border-bottom split-line
    .editor-header
      padding 3px
      margin-bottom 3px
      border-bottom split-line
      .iconfont
        cursor pointer
        margin 0 5px
        transition color 0.1s
        &:hover
          color cm-icon-hover
  .editor-output
    .output-header
      width 70px
      min-height 30px
      line-height 30px
    .output-tips
      font-size 18px
    .output-row
      display flex
      flex-direction row
      margin-top 10px
      .output-title
        width 70px
        min-height 35px
      .output-content
        width 100%
        padding 4px
        line-height 1
        background-color #f4f4f4
        border-radius 6px
</style>
